#include "StdAfx.h"
#include "PluginShimImpl.h"
#include "PSApi.h"
#include "comutil.h"

//Copyright 2007 Scott Hanselman
// http://www.hanselman.com/blog
//  with C++ help from Matt Davis

PluginShimImpl::PluginShimImpl(int function)
{
	// TODO: handle errors (missing ProgID, etc)- but doesn't look like Create lets you do so...
	// TODO: explicitly host the CLR, but lazy COM activation is easier for hackery...

	CLSID c;

	CLSIDFromProgID(MANAGED_PLUGIN_PROGID, &c);

	CoCreateInstance(c, NULL, CLSCTX_INPROC_SERVER, IID_IOptimusPlugin, (void**)&pManagedImpl);
}

PluginShimImpl::~PluginShimImpl(void)
{
	// TODO: clean up the managed instance, but meh...
	pManagedImpl->Release();
}

BOOL PluginShimImpl::Paint(HDC hdc)
{
	BOOL retVal;
	
	pManagedImpl->Paint((void*)hdc, &retVal);

	return retVal;
}

// called on keydown from device thread. should return fast.
// button: pressed button, from 1 to MAX_BUTTON.
void PluginShimImpl::OnKeyDown()
{
	pManagedImpl->OnKeyDown();
}

// to collect INFO_* values from plugin 
LPARAM PluginShimImpl::GetInfo(int index)
{
	LPARAM retVal;

	pManagedImpl->GetInfo(index, (int*)&retVal);

	return retVal;
}


// allows to get properties from plugin instance
// index: from PLUGIN_PROPERTIES and PLUGIN_SHARED_PROPERTIES until false is return.
// should return value and name (no longer then MAX_PROPERTY_LENGTH bytes)
BOOL PluginShimImpl::GetProperty(int index, char *name, char *value)
{
	BOOL retVal;
	
	_bstr_t bstName, bstValue;
	
	HRESULT hr = pManagedImpl->GetProperty(index, bstName.GetAddress(), bstValue.GetAddress(), &retVal);

	// copy back the managed strings
	if(bstName.GetBSTR())
		strcpy_s(name, 256, (char*)bstName);
	else
		*name = 0;

	if(bstValue.GetBSTR())
		strcpy_s(value, 256, (char*)bstValue);
	else
		*value = 0;

	return retVal;
}


// allows to set plugin instance properties
// called for every name got with GetProperty with actial value from registry
BOOL PluginShimImpl::SetProperty(const char *name, const char *value)
{
	BOOL retVal;

	HRESULT hr = pManagedImpl->SetProperty((unsigned char*)name, (unsigned char*)value, &retVal);

	return retVal;
}

// shows plugin properties dialog. 
// should return true if properties has been changed.
BOOL PluginShimImpl::ShowProperties(HWND hwnd)
{
	BOOL retVal;

	pManagedImpl->ShowProperties(hwnd, &retVal);

	return retVal;
}

// plugin life cicle is OnEvent(ACTIVATE) -> Paint(),Paint().. -> OnEvent(DEACTIVATE)
// ACTIVATE/DEACTIVATE can be used to allocate resources requied for painting
// should return TRUE. should return fast.
BOOL PluginShimImpl::OnEvent(int evt)
{
	BOOL retVal;

	pManagedImpl->OnEvent(evt, &retVal);

	return retVal;
}

